///////////////////////////////////////////////////////////////////////////////
//
// lighthouse3D - 3D Software Library
//
// File: lh3dwrapper.cpp
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2003-2013 Marcus Reinhardt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
//
// You can find a copy of the GNU General Public License (gpl.txt) in the
// directory of the library.
//
///////////////////////////////////////////////////////////////////////////////
#include "lh3dwrapper.h"
#include "C3DLibrary.h"
#include "C3DLibInterface.h"

// Library instance
C3DLibrary lh3D;
// Interface instance
C3DLibInterface lh3DIF;

///////////////////////////////////////////////////////////////////////////////
// lh3dwrapper_lib_init( ... )
///////////////////////////////////////////////////////////////////////////////
unsigned char lh3dwrapper_lib_init(int scrWidth, int scrHeight, TEnvInformation *pEI)
{
  TAppLibrarySetup *pALS;

  /*
   * Bind library instance to interface instance
   */
  lh3DIF.bindLibrary(&lh3D);

  /*
   * Call lh3D application setup
   */
  pALS = lh3dappmain_event_setup(pEI);
	
  if (pALS != NULL) {
    /*
	 * Setup worker threads if multi core support is compiled in
	 */
#ifdef __MULTI_CORE_SUPPORT
    pEI->nrWorkerThreads = pALS->nrWorkerThreads;
#endif

	/*
	 * Setup screen layout
	 */
	pALS->screenWidth = scrWidth;
    pALS->screenHeight = scrHeight;

    /*
	 * Setup renderer model
	 */
	if (pALS->renderMode == 0)
	    lh3DIF.setupRenderer(_nullRenderer_);
  	if (pALS->renderMode == 1)
		lh3DIF.setupRenderer(_wireFrameRenderer_);
	if (pALS->renderMode == 2)
		lh3DIF.setupRenderer(_texRenderer_);

    /*
	 * Setup shading model
	 */
	if (pALS->shadingMode == 1)
		lh3DIF.setupShader(_noTexShader_);
	if (pALS->shadingMode == 2)
		lh3DIF.setupShader(_lambertTexShader_);
	if (pALS->shadingMode == 3)
		lh3DIF.setupShader(_gouraudTexShader_);
	if (pALS->shadingMode == 4)
		lh3DIF.setupShader(_phongTexShader_);

    /*
	 * Setup lighting model
	 */
	if (pALS->lightingMode == 1)
		lh3DIF.setupLighting(_lambertLighting_);
	if (pALS->lightingMode == 2)
		lh3DIF.setupLighting(_phongLighting_);


    /*
	 * Setup post rendering anti-aliasing (full screen anti-aliasing)
	 */
	if (pALS->fsaaliasMode == 0)
		lh3DIF.setupFSAAFilter(_noFSAntiAliasing_);
	if (pALS->fsaaliasMode == 1)
		lh3DIF.setupFSAAFilter(_bilinearFSAntiAliasing_);
	if (pALS->fsaaliasMode == 2)
		lh3DIF.setupFSAAFilter(_bilinear2XFSAntiAliasing_);

	/*
	 * Setup back face culling
	 */
	if (pALS->bfcullingMode == 1)
  	  lh3DIF.setupBFCulling(_backFaceCulling_);

	/*
	 * Setup texture filtering
	 */
	if (pALS->texFilterMode == 0) 
		lh3DIF.setupTexFilter(_noTexFilter_);
	if (pALS->texFilterMode == 1) 
		lh3DIF.setupTexFilter(_linearTexFilter_);
	if (pALS->texFilterMode == 2) 
		lh3DIF.setupTexFilter(_bilinearTexFilter_);
  }

  /*
   * Setup virtual screen
   */
  lh3DIF.resizeScreen(scrWidth, scrHeight);

  /*
   * Call lh3D application init
   */
  return lh3dappmain_event_init(&lh3D);
}

///////////////////////////////////////////////////////////////////////////////
// lh3dwrapper_lib_task( ... )
///////////////////////////////////////////////////////////////////////////////
unsigned char lh3dwrapper_lib_task(void)
{
  unsigned char requestScreenUpdate;

  /*
   * Call lh3D application period task
   */
  requestScreenUpdate = lh3dappmain_event_task();

  if (requestScreenUpdate) {
    /*
     * Clear buffer, render 3D scene, update UI elements
     */
    lh3DIF.clear();
    if (!lh3DIF.update3DScene()) {
	  return 0;
    }
    lh3DIF.updateGUIElements();
  }

  return requestScreenUpdate;
}

///////////////////////////////////////////////////////////////////////////////
// lh3dwrapper_lib_out( ... )
///////////////////////////////////////////////////////////////////////////////
unsigned char lh3dwrapper_lib_out(void)
{
  return 1;
}

///////////////////////////////////////////////////////////////////////////////
// lh3dwrapper_lib_in( ... )
///////////////////////////////////////////////////////////////////////////////
unsigned char lh3dwrapper_lib_in(int lmkey, int mmkey, int rmkey, int horzPos, int vertPos)
{
  return lh3dappmain_event_mousechanged(lmkey, mmkey, rmkey, horzPos, vertPos);
}

///////////////////////////////////////////////////////////////////////////////
// lh3dwrapper_lib_resize( ... )
///////////////////////////////////////////////////////////////////////////////
unsigned char  lh3dwrapper_lib_resize(int width, int height)
{
  lh3DIF.resizeScreen(width, height);

  return lh3dappmain_event_resize(width, height);
}

///////////////////////////////////////////////////////////////////////////////
// lh3dappmain_lib_startworkerthread( ... )
///////////////////////////////////////////////////////////////////////////////
#ifdef __MULTI_CORE_SUPPORT
unsigned long  lh3dappmain_lib_startworkerthread(unsigned char nrThreadParams, unsigned char *threadParams)
{
  return lh3D.workerThread(nrThreadParams, threadParams);
}
#endif

///////////////////////////////////////////////////////////////////////////////
// lh3dwrapper_lib_ptr( ... )
///////////////////////////////////////////////////////////////////////////////
C3DLibrary *lh3dwrapper_lib_ptr(void)
{
  return &lh3D;
}
